﻿using System;
using System.Data;
using System.Data.SqlTypes;

namespace HugMe.DataLayer
{

	public static class DataReaderExtensions
	{
		public static DateTime ToSqlDateTime(this DateTime date)
		{
			DateTime minValue = SqlDateTime.MinValue.Value;
			DateTime maxValue = SqlDateTime.MaxValue.Value;
			return date < minValue ? minValue : (date > maxValue ? maxValue : date);
		}

		/****************************************************/

		public static string GetStringOrNull(this IDataReader reader, string columnName)
		{
			int ordinal = reader.GetOrdinalOrDefault(columnName);
			return ordinal < 0 || reader.IsDBNull(ordinal) ? null : reader.GetString(ordinal);
		}

		public static bool GetBooleanOrDefault(this IDataReader reader, string columnName, bool @default = false)
		{
			int ordinal = reader.GetOrdinalOrDefault(columnName);
			return ordinal < 0 || reader.IsDBNull(ordinal) ? @default : reader.GetBoolean(ordinal);
		}

		public static byte GetByteOrDefault(this IDataReader reader, string columnName, byte @default = 0)
		{
			int ordinal = reader.GetOrdinalOrDefault(columnName);
			return ordinal < 0 || reader.IsDBNull(ordinal) ? @default : reader.GetByte(ordinal);
		}

		public static int GetInt32OrDefault(this IDataReader reader, string columnName, int @default = 0)
		{
			int ordinal = reader.GetOrdinalOrDefault(columnName);
			return ordinal < 0 || reader.IsDBNull(ordinal) ? @default : reader.GetInt32(ordinal);
		}

		public static Guid GetGuidOrDefault(this IDataReader reader, string columnName)
		{
			int ordinal = reader.GetOrdinalOrDefault(columnName);
			return ordinal < 0 || reader.IsDBNull(ordinal) ? Guid.Empty : reader.GetGuid(ordinal);
		}

		public static bool? GetBooleanOrNull(this IDataReader reader, string columnName)
		{
			int ordinal = reader.GetOrdinalOrDefault(columnName);
			return ordinal < 0 || reader.IsDBNull(ordinal) ? (bool?)null : reader.GetBoolean(ordinal);
		}

		public static Guid? GetGuidOrNull(this IDataReader reader, string columnName)
		{
			int ordinal = reader.GetOrdinalOrDefault(columnName);
			return ordinal < 0 || reader.IsDBNull(ordinal) ? (Guid?)null : reader.GetGuid(ordinal);
		}

		public static long? GetInt64OrNull(this IDataReader reader, string columnName)
		{
			int ordinal = reader.GetOrdinalOrDefault(columnName);
			return ordinal < 0 || reader.IsDBNull(ordinal) ? (long?)null : reader.GetInt64(ordinal);
		}

		public static int? GetInt32OrNull(this IDataReader reader, string columnName)
		{
			int ordinal = reader.GetOrdinalOrDefault(columnName);
			return ordinal < 0 || reader.IsDBNull(ordinal) ? (int?)null : reader.GetInt32(ordinal);
		}

		public static DateTime? GetDateTimeOrNull(this IDataReader reader, string columnName)
		{
			int ordinal = reader.GetOrdinalOrDefault(columnName);
			return ordinal < 0 || reader.IsDBNull(ordinal) ? (DateTime?)null : reader.GetDateTime(ordinal);
		}

		/****************************************************/

		public static int GetOrdinalOrDefault(this IDataRecord dr, string columnName)
		{
			for (int i = 0; i < dr.FieldCount; i++)
			{
				if (dr.GetName(i).Equals(columnName, StringComparison.InvariantCultureIgnoreCase))
					return i;
			}
			return -1;
		}

		/****************************************************/

		public static decimal GetDecimal(this IDataReader reader, string columnName)
		{
			return reader.GetDecimal(reader.GetOrdinal(columnName));
		}

		public static int GetInt32(this IDataReader reader, string columnName)
		{
			return reader.GetInt32(reader.GetOrdinal(columnName));
		}

		public static float GetFloat(this IDataReader reader, string columnName)
		{
			return reader.GetFloat(reader.GetOrdinal(columnName));
		}

		public static byte GetByte(this IDataReader reader, string columnName)
		{
			return reader.GetByte(reader.GetOrdinal(columnName));
		}

		public static string GetString(this IDataReader reader, string columnName)
		{
			return reader.GetString(reader.GetOrdinal(columnName));
		}

		public static bool GetBoolean(this IDataReader reader, string columnName)
		{
			return reader.GetBoolean(reader.GetOrdinal(columnName));
		}

		public static Guid GetGuid(this IDataReader reader, string columnName)
		{
			return reader.GetGuid(reader.GetOrdinal(columnName));
		}

		public static short GetInt16(this IDataReader reader, string columnName)
		{
			return reader.GetInt16(reader.GetOrdinal(columnName));
		}

		public static long GetInt64(this IDataReader reader, string columnName)
		{
			return reader.GetInt64(reader.GetOrdinal(columnName));
		}

		public static DateTime GetDateTime(this IDataReader reader, string columnName)
		{
			return reader.GetDateTime(reader.GetOrdinal(columnName));
		}

		public static int GetIndex(this IDataReader dr, string name)
		{
			for (int i = 0; i < dr.FieldCount; i++)
				if (dr.GetName(i) == name) return i;
			return -1;
		}
	}
}